import { ref, onMounted, onUnmounted } from 'vue'

export interface Star {
  x: number
  y: number
  r: number
  a: number
  tw: number
  vx: number
  vy: number
  parallax: number
  hue: number
}

export interface Meteor {
  x: number
  y: number
  len: number
  angle: number
  speed: number
  life: number
  alpha: number
}

export function useStarfield() {
  const starCanvasRef = ref<HTMLCanvasElement>()
  
  let rafId = 0
  let resizeHandler: (() => void) | null = null
  let mouseHandler: ((e: MouseEvent) => void) | null = null
  let mouseLeaveHandler: (() => void) | null = null
  const mouse = { x: 0, y: 0 }

  const initStarfield = () => {
    const canvas = starCanvasRef.value
    if (!canvas) return
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    const setSize = () => {
      const dpr = window.devicePixelRatio || 1
      canvas.width = Math.floor(window.innerWidth * dpr)
      canvas.height = Math.floor(window.innerHeight * dpr)
      canvas.style.width = window.innerWidth + 'px'
      canvas.style.height = window.innerHeight + 'px'
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
    }

    setSize()

    const area = window.innerWidth * window.innerHeight
    const base = Math.max(80, Math.floor(area / 9000))

    function makeStars(count: number, parallax: number, speed: number, size: [number, number]): Star[] {
      return new Array(count).fill(0).map(() => ({
        x: Math.random() * window.innerWidth,
        y: Math.random() * window.innerHeight,
        r: Math.random() * size[1] + size[0],
        a: Math.random() * 0.6 + 0.25,
        tw: Math.random() * Math.PI * 2,
        vx: (Math.random() - 0.5) * speed,
        vy: (Math.random() - 0.5) * speed,
        parallax,
        hue: 220 + Math.random() * 40
      }))
    }

    const stars: Star[] = [
      ...makeStars(Math.floor(base * 0.4), 6, 0.03, [0.6, 1.4]), // 远层
      ...makeStars(Math.floor(base * 0.35), 10, 0.05, [0.4, 1.0]), // 中层
      ...makeStars(Math.floor(base * 0.25), 14, 0.07, [0.2, 0.8]) // 近层
    ]

    const meteors: Meteor[] = []

    const spawnMeteor = () => {
      const fromLeft = Math.random() < 0.5
      const x = fromLeft ? -50 : Math.random() * window.innerWidth * 0.6
      const y = fromLeft ? Math.random() * window.innerHeight * 0.6 : -50
      const angle = (Math.PI / 4) + (Math.random() * 0.3)
      const speed = 4 + Math.random() * 2
      const len = 120 + Math.random() * 120
      const life = 1.2
      meteors.push({ x, y, len, angle, speed, life, alpha: 1 })
    }

    const draw = () => {
      const w = window.innerWidth
      const h = window.innerHeight
      ctx.clearRect(0, 0, w, h)

      // 双层星云叠加
      const g1 = ctx.createRadialGradient(w * 0.2, h * 0.3, 0, w * 0.2, h * 0.3, w)
      g1.addColorStop(0, 'rgba(58, 12, 163, 0.08)')
      g1.addColorStop(1, 'rgba(0, 0, 0, 0)')
      ctx.fillStyle = g1
      ctx.fillRect(0, 0, w, h)

      const g2 = ctx.createRadialGradient(w * 0.8, h * 0.7, 0, w * 0.8, h * 0.7, w)
      g2.addColorStop(0, 'rgba(0, 180, 255, 0.04)')
      g2.addColorStop(1, 'rgba(0, 0, 0, 0)')
      ctx.fillStyle = g2
      ctx.fillRect(0, 0, w, h)

      // 星层绘制（视差 + 漂移 + 闪烁）
      for (const s of stars) {
        s.tw += 0.015
        const alpha = s.a + Math.sin(s.tw) * 0.2
        s.x += s.vx
        s.y += s.vy
        if (s.x < -2) s.x = w + 2
        if (s.x > w + 2) s.x = -2
        if (s.y < -2) s.y = h + 2
        if (s.y > h + 2) s.y = -2

        const sx = s.x + mouse.x * s.parallax
        const sy = s.y + mouse.y * s.parallax
        ctx.beginPath()
        ctx.arc(sx, sy, s.r, 0, Math.PI * 2)
        ctx.closePath()
        ctx.fillStyle = `hsla(${s.hue}, 80%, 85%, ${alpha})`
        ctx.fill()
      }

      // 流星绘制
      for (let i = meteors.length - 1; i >= 0; i--) {
        const m = meteors[i]
        m.x += Math.cos(m.angle) * m.speed
        m.y += Math.sin(m.angle) * m.speed
        m.life -= 0.01
        m.alpha = Math.max(0, m.life)

        if (m.alpha <= 0 || m.x < -200 || m.y < -200 || m.x > w + 200 || m.y > h + 200) {
          meteors.splice(i, 1)
          continue
        }

        ctx.save()
        ctx.globalAlpha = 0.7 * m.alpha
        ctx.strokeStyle = 'rgba(255,255,255,0.9)'
        ctx.lineWidth = 2
        ctx.beginPath()
        ctx.moveTo(m.x, m.y)
        ctx.lineTo(m.x - Math.cos(m.angle) * m.len, m.y - Math.sin(m.angle) * m.len)
        ctx.stroke()

        ctx.beginPath()
        ctx.arc(m.x, m.y, 2.5, 0, Math.PI * 2)
        ctx.fillStyle = 'rgba(255,255,255,0.95)'
        ctx.fill()
        ctx.restore()
      }

      // 随机生成流星
      if (Math.random() < 0.004) spawnMeteor()

      rafId = requestAnimationFrame(draw)
    }

    rafId = requestAnimationFrame(draw)

    resizeHandler = () => { setSize() }
    window.addEventListener('resize', resizeHandler)

    mouseHandler = (e: MouseEvent) => {
      const cx = window.innerWidth / 2
      const cy = window.innerHeight / 2
      mouse.x = ((e.clientX - cx) / cx) * 12
      mouse.y = ((e.clientY - cy) / cy) * 12
    }
    mouseLeaveHandler = () => { mouse.x = 0; mouse.y = 0 }
    window.addEventListener('mousemove', mouseHandler)
    window.addEventListener('mouseleave', mouseLeaveHandler)
  }

  const cleanup = () => {
    if (rafId) cancelAnimationFrame(rafId)
    if (resizeHandler) window.removeEventListener('resize', resizeHandler)
    if (mouseHandler) window.removeEventListener('mousemove', mouseHandler)
    if (mouseLeaveHandler) window.removeEventListener('mouseleave', mouseLeaveHandler)
    resizeHandler = null
    mouseHandler = null
    mouseLeaveHandler = null
  }

  onMounted(() => {
    initStarfield()
  })

  onUnmounted(() => {
    cleanup()
  })

  return {
    starCanvasRef,
    initStarfield,
    cleanup
  }
}